﻿using System;

namespace tuimg.helpers
{
    using System.IO;
    using tuimg.element;
    using tuimg.structs;

    internal partial class helper
    {
        public static int abs(int a)
        {
            return (a & 0x80000000) != 0 ? ~a + 1 : a;
        }
        public static float fast_sqrt(int a)
        {
            if (a == 0) return 0;
            var x = convert_float(0x5f3759df - (convert_int(a) >> 1));
            return (x * (1.5f - 0.5f * a * x * x)) *a;
        }
        public static float convert_float(int a)
        {
            return BitConverter.ToSingle(BitConverter.GetBytes(a), 0);
        }
        public static int convert_int(float a)
        {
            return BitConverter.ToInt32(BitConverter.GetBytes(a), 0);
        }
        public static int toint8(byte b)
        {
            return (b >> 7) == 1 ? -128|b : b;
        }
        public static double calc_line_length(int x1, int y1, int x2, int y2)
        {
            return fast_sqrt(abs(((x2 - x1) << 1)) + abs(((y2 - y1) << 1)));
        }
        public static double calc_line_length_2(int x1, int y1, int x2, int y2)
        {
            var linelen = calc_line_length(x1, y1, x2, y2);
            return linelen* linelen;
        }
        public static int round_up(double a)
        {
            if (a % 1 > 0) return (int)a + 1;
            return (int)a;
        }
        public static int round_down(double a)
        {
            return (int)a;
        }
        public static int round(double a)
        {
            if (a % 1 < 0.8) return (int)a;
            return (int)a + 1;
        }
        public static int min(int a, int b)
        {
            if (a > b) return b;
            return a;
        }
        internal static struct_path_point calc_middle_point(struct_path_point p0, struct_path_point p1)
        {
            return new struct_path_point { x = (int)((p0.x >> 1) + (p1.x >> 1)), y = (int)((p0.y >> 1) + (p1.y >> 1)) };
        }
        internal static byte paethPrediction(byte a, byte b, byte c)
        {
            int p = a + b - c;
            int pa = abs(p - a);
            int pb = abs(p - b);
            int pc = abs(p - c);

            if (pa <= pb && pa <= pc)
                return a;
            else if (pb <= pc)
                return b;
            else
                return c;
        }
        internal static byte blend_color(byte colora, byte colorb, byte alpha)
        {
            return (byte)((((colora * alpha + colorb * (0xff - alpha)) >> 8) & 0xffU) + 1);
        }
        internal static float max(float a, float b)
        {
            return a > b ? a : b;
        }
        internal static float min(float a, float b)
        {
            return a < b ? a : b;
        }
    }
}
